// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.reports.editor.design.utils;

import java.util.Comparator;
import java.util.HashMap;
import java.util.SortedSet;
import java.util.TreeSet;

import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;

/**
 * This class integrated some methods that will be used in GUI. It provides the information that GUI will use and is
 * called widely. *
 * 
 * /** Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf Qiang.Zhang.Adolf@gmail.com 2008-2-22 qiang.zhang $
 * 
 */
public class DEUtil {

    /**
     * Property name for element labelContent.
     */
    public static final String ELEMENT_LABELCONTENT_PROPERTY = "labelContent"; //$NON-NLS-1$

    private static HashMap propertiesMap = new HashMap();

    /**
     * Gets the element name. The object is a long string that separated with the separator "."
     * 
     * @param obj the object
     * @return the name behind the last separator "."
     */

    public static String getElementName(Object obj) {
        if (obj instanceof Class) {
            obj = ((Class) obj).getName();
        }
        return obj.toString().substring(obj.toString().lastIndexOf(".") + 1); //$NON-NLS-1$
    }

    /**
     * Map GUI defined property key to DE defined property key
     * 
     * @param key
     * @return DE defined property key
     */
    public static String getGUIPropertyKey(String key) {
        if (key != null) {
            return (String) propertiesMap.get(key);
        }
        return null;
    }

    /**
     * Checks if the value can be converted to a valid Integer.
     * 
     * @param val
     * @return true if the value can be converted to a valid Integer, else false.
     */
    public static boolean isValidInteger(String val) {
        try {
            Integer.parseInt(val);
        } catch (Exception e) {
            return false;
        }

        return true;
    }

    /**
     * Checks if the value is a valid number, including any integer and float, double.
     * 
     * @param val
     */
    public static boolean isValidNumber(String val) {
        try {
            Double.parseDouble(val);
        } catch (Exception e) {
            return false;
        }

        return true;
    }

    /**
     * Try to split the given value to String[2]. The result format is as follows: [number][other]. If either part can
     * not be determined, it will leave null.
     * 
     * @param value given string value
     * @return [number][other]
     */
    public static String[] splitString(String value) {
        String[] spt = new String[2];

        if (value != null) {
            for (int i = value.length(); i > 0; i--) {
                if (isValidNumber(value.substring(0, i))) {
                    spt[0] = value.substring(0, i);
                    spt[1] = value.substring(i, value.length());

                    break;
                }
            }

            if (spt[0] == null && spt[1] == null) {
                spt[1] = value;
            }
        }

        return spt;
    }

    /**
     * If given value if null, return an empty string, or return itself.
     * 
     * @param value a String value.
     * @return non-null value.
     */
    public static String resolveNull(String value) {
        return value == null ? "" : value; //$NON-NLS-1$
    }

    /**
     * Converts the RGB object value to a String, the String format is "r,g,b", no quotation marks.
     * 
     * @param rgb RGB value.
     * @return String value.
     */
    public static String getRGBText(RGB rgb) {
        if (rgb != null) {
            return rgb.red + "," + rgb.green + "," + rgb.blue; //$NON-NLS-1$ //$NON-NLS-2$
        }

        return ""; //$NON-NLS-1$
    }

    /**
     * Converts the String value to an RGB object value, the String format is "r,g,b", no quotation marks.
     * 
     * @param val String value.
     * @return RGB value.
     */
    public static RGB getRGBValue(String val) {
        if (val != null) {
            if (val.startsWith("#")) //$NON-NLS-1$
            {
                int rgb = ColorUtil.parseColor(val);

                if (rgb != -1) {
                    return getRGBValue(rgb);
                }
            } else {
                String[] ss = val.split(","); //$NON-NLS-1$
                if (ss.length == 3) {
                    try {
                        int r = Integer.parseInt(ss[0]);
                        int g = Integer.parseInt(ss[1]);
                        int b = Integer.parseInt(ss[2]);

                        return new RGB(r, g, b);
                    } catch (NumberFormatException e) {
                        return null;
                    }
                }
            }
        }

        return null;
    }

    /**
     * Converts an Integer value to an RGB object value, the Integer format is 0xRRGGBB.
     * 
     * @param rgbValue Integer value.
     * @return RGB value.
     */
    public static RGB getRGBValue(int rgbValue) {
        if (rgbValue == -1) {
            return null;
        }

        return new RGB((rgbValue >> 16) & 0xff, (rgbValue >> 8) & 0xff, rgbValue & 0xff);
    }

    /**
     * Converts an RGB object value to an Integer value, the Integer format is 0xRRGGBB.
     * 
     * @param rgb RGB value.
     * @return Integer value.
     */
    public static int getRGBInt(RGB rgb) {
        if (rgb == null) {
            return -1;
        }

        return ((rgb.red & 0xff) << 16) | ((rgb.green & 0xff) << 8) | (rgb.blue & 0xff);
    }

    /**
     * Since "&" in menu text has special meaning, we must escape it before displaying.
     * 
     * @param src Source text.
     * @return Escaped text.
     */
    public static String getEscapedMenuItemText(String src) {
        if (src != null && src.indexOf('&') != -1) {
            src = src.replaceAll("\\&", "&&"); //$NON-NLS-1$ //$NON-NLS-2$
        }

        return src;
    }

    /**
     * Returns all font names for current system.
     * 
     * NOTES: Java 1.4 only support true type fonts.
     * 
     * @return font names.
     */
    public static String[] getSystemFontNames() {
        return getSystemFontNames(null);
    }

    /**
     * Returns all font names for current system. NOTES: Java 1.4 only support true type fonts.
     * 
     * @param comparator Sort comparator.
     * @return font names.
     */
    public static String[] getSystemFontNames(Comparator comparator) {
        FontData[] fontDatas = (FontData[]) Display.getCurrent().getFontList(null, false);
        SortedSet set = new TreeSet(comparator);
        for (int i = 0; i < fontDatas.length; i++) {
            set.add(fontDatas[i].getName());
        }
        fontDatas = (FontData[]) Display.getCurrent().getFontList(null, true);
        for (int i = 0; i < fontDatas.length; i++) {
            set.add(fontDatas[i].getName());
        }
        String[] fonts = new String[set.size()];
        set.toArray(fonts);
        return fonts;
    }

    /**
     * Escapes \ and " following standard of Javascript
     * 
     * @param str
     * @return new string after escape special character
     */
    public static String escape(String str) {
        String[][] chars = { { "\\\\", "\"", "\'", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
        }, { "\\\\\\\\", "\\\\\"", "\\\\\'", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
        } };
        String result = str;
        for (int i = 0; i < chars[0].length; i++) {
            result = result.replaceAll(chars[0][i], chars[1][i]);
        }
        return result;
    }

    /**
     * Gets decimal string given the number of zeros.
     */
    public static String getDecmalStr(int decPlaces) {

        String defaultDecs = "0000000000"; //$NON-NLS-1$
        String decStr = ""; //$NON-NLS-1$
        if (decPlaces > 0 && decPlaces < 10) {
            decStr = defaultDecs.substring(0, decPlaces);
        } else if (decPlaces >= 10) {
            if (decPlaces > 100) {
                decPlaces = 100;
            }
            int quotient = decPlaces / 10;
            int remainder = decPlaces % 10;

            StringBuffer s = new StringBuffer(100);
            for (int i = 0; i < quotient; i++) {
                s.append(defaultDecs);
            }
            s.append(defaultDecs.substring(0, remainder));

            decStr = s.toString();
        }
        return decStr;
    }

    /**
     * Checks if two strings have same value.
     * 
     * @param str1
     * @param str2
     * @return
     */
    public static boolean isSameString(String str1, String str2) {
        if (str1 == null && str2 == null) {
            return true;
        }
        if (str1 != null && str1.equals(str2)) {
            return true;
        }
        return false;
    }

    /**
     * The group container is ListingHandler, list, table, and so on.
     */
    public static final String TYPE_GROUP_LISTING = "listing";

    /**
     * The group container is GroupHandler
     */
    public static final String TYPE_GROUP_GROUP = "group";

    /**
     * other container, has none group.
     */
    public static final String TYPE_GROUP_NONE = "none";

    /**
     * Get the string enclosed with quote.
     * 
     * @param string
     * @return
     */
    public static String AddQuote(String string) {
        if (string != null && (!(string.startsWith("\"") && string.endsWith("\"")))) //$NON-NLS-1$//$NON-NLS-2$
        {
            return "\"" + string + "\""; //$NON-NLS-1$//$NON-NLS-2$
        }
        return string;
    }

    /**
     * Remove the quote if the string enclosed width quote .
     * 
     * @param string
     * @return
     */
    public static String RemoveQuote(String string) {
        if (string != null && string.length() >= 2 && string.startsWith("\"") //$NON-NLS-1$
                && string.endsWith("\"")) //$NON-NLS-1$
        {
            return string.substring(1, string.length() - 1);
        }
        return string;
    }

}